package com.ms.game.rebate.db;

import java.math.BigDecimal;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import com.ms.game.bank.BankMoneyChangeWay;
import com.ms.game.bank.db.BankDAO;
import com.ms.game.bank.db.BankLogModel;
import com.ms.game.lobby.GameLobbyModule;
import com.ms.game.rebate.RebateModifyStatus;
import com.ms.game.rebate.RebateType;
import com.ms.game.rebate.message.SGetRebateCoinResponse;
import com.ms.player.Player;
import com.ms.service.error.ErrorCode;
import com.ms.service.module.analysisgroup.AnalysisGroupProcessor;
import com.ms.service.module.analysisgroup.CoinExpenditureWay;
import com.ms.service.module.datacenterlite.CentralAsyncCommand;
import com.xpec.c4.db.dao.PlayerDAO;
import com.xpec.c4.game.common.Helper;
import com.xpec.c4.game.utility.GUID;
import com.xpec.c4.game.utility.GUIDFactory;
import com.xpec.c4.game.utility.GUIDType;
import com.xpec.c4.message.MessageTypes;
import com.xpec.c4.service.message.MessageAction;

public class GetAllRebateCoinsDCLAsync extends CentralAsyncCommand {

	private static final long serialVersionUID = -4902747128212317742L;
	public GUID playerID;
	public GUID accountID;
	public GUID sessionID;
	public String playerName;

	public GetAllRebateDatas getAllRebateDatas;
		
	private BigDecimal afterBankGold = BigDecimal.ZERO;

	private BankMoneyChangeWay bankMoneychangeWay;
	
	/**
	 * 處理完畢要送給統計的資訊
	 */
	private HashMap<CoinExpenditureWay, BigDecimal> sendToAnalysisMap = new HashMap<CoinExpenditureWay, BigDecimal>();

	@Override
	public void asyncExecute() throws Exception {
		Player player = PlayerDAO.loadPlayerByGuid(playerID);
		//先取得玩家銀行的錢
		afterBankGold = player.getBankGoldCoin();
		
		//讀出回饋金欄位裡可領的回饋金
		getAllRebateDatas.rebateModels = RebateDAO.getAllReabteDatas(playerID);
		String orderId = GUIDFactory.createUUID(GUIDType.TYPE_BANK_MONEY).toString();
		ArrayList<BankLogModel> bankLogModels = new ArrayList<BankLogModel>();
		ArrayList<RebateLogModel> rebateLogModels = new ArrayList<RebateLogModel>();
		
		// 包月每日登入獎勵
		if(getAllRebateDatas.monthlyDailyAward.isSuccess()){
			bankMoneychangeWay = BankMoneyChangeWay.ADD_MONTHLY_FEE_DAILY_PAY;
			afterBankGold = Helper.add(afterBankGold, getAllRebateDatas.monthlyDailyAward.getRebateCoins());
			getAllRebateDatas.totalGold = Helper.add(getAllRebateDatas.totalGold, getAllRebateDatas.monthlyDailyAward.getRebateCoins());
			
			//bank log
			BankLogModel bankLogModel = new BankLogModel();
			bankLogModel.setOrderId(orderId);
			bankLogModel.setAccountId(accountID.toString());
			bankLogModel.setPlayerId(playerID.toString());
			bankLogModel.setPlayerName(playerName);
			bankLogModel.setChangeWay(bankMoneychangeWay.getId());
			bankLogModel.setChangeWayDesc(bankMoneychangeWay.getDesc());
			bankLogModel.setBankGoldChangeValue(getAllRebateDatas.monthlyDailyAward.getRebateCoins());
			bankLogModel.setBankGoldBeforeChange(Helper.sub(afterBankGold, getAllRebateDatas.monthlyDailyAward.getRebateCoins()));
			bankLogModel.setBankGoldAfterChange(afterBankGold);
			//加到log list
			bankLogModels.add(bankLogModel);

			// rebatelog
			RebateLogModel rebateLogModel = new RebateLogModel();
			rebateLogModel.setOrderId(orderId);
			rebateLogModel.setBelongsDate(new Date(getAllRebateDatas.monthlyDailyAward.getBelongsDate()));
			rebateLogModel.setStatus(RebateModifyStatus.HAVE_RECEIVED);
			rebateLogModel.setTotalRebateCoin(getAllRebateDatas.monthlyDailyAward.getRebateCoins());
			rebateLogModel.setPlayerName(playerName);
			rebateLogModel.setPlayerId(playerID.toString());
			rebateLogModel.setType(RebateType.MONTHLY_FEE_DAILY_PAY.getId());
			rebateLogModel.setTypeDesc(RebateType.MONTHLY_FEE_DAILY_PAY.getDesc());
			//加到log list
			rebateLogModels.add(rebateLogModel);
			
			//更新包月每日獎勵 stage回db
			BankDAO.UpdatePlayerMonthlyFee(playerID, getAllRebateDatas.monthlyDailyAward.getBelongsDate(), getAllRebateDatas.monthlyDailyAward.getMonthlyFeePayStage());
			//新增到傳給統計的資訊中
			addCoinExpenditure(CoinExpenditureWay.MONTH_DAILY_REWARD, getAllRebateDatas.monthlyDailyAward.getRebateCoins());
			
		}
		
		// 包月每日登入獎勵
		if(getAllRebateDatas.weeklyDailyAward.isSuccess()){
			bankMoneychangeWay = BankMoneyChangeWay.ADD_WEEKLY_FEE_DAILY_PAY;
			afterBankGold = Helper.add(afterBankGold, getAllRebateDatas.weeklyDailyAward.getRebateCoins());
			getAllRebateDatas.totalGold = Helper.add(getAllRebateDatas.totalGold, getAllRebateDatas.weeklyDailyAward.getRebateCoins());
			
			//bank log
			BankLogModel bankLogModel = new BankLogModel();
			bankLogModel.setOrderId(orderId);
			bankLogModel.setAccountId(accountID.toString());
			bankLogModel.setPlayerId(playerID.toString());
			bankLogModel.setPlayerName(playerName);
			bankLogModel.setChangeWay(bankMoneychangeWay.getId());
			bankLogModel.setChangeWayDesc(bankMoneychangeWay.getDesc());
			bankLogModel.setBankGoldChangeValue(getAllRebateDatas.weeklyDailyAward.getRebateCoins());
			bankLogModel.setBankGoldBeforeChange(Helper.sub(afterBankGold, getAllRebateDatas.weeklyDailyAward.getRebateCoins()));
			bankLogModel.setBankGoldAfterChange(afterBankGold);
			//加到log list
			bankLogModels.add(bankLogModel);

			// rebatelog
			RebateLogModel rebateLogModel = new RebateLogModel();
			rebateLogModel.setOrderId(orderId);
			rebateLogModel.setBelongsDate(new Date(getAllRebateDatas.weeklyDailyAward.getBelongsDate()));
			rebateLogModel.setStatus(RebateModifyStatus.HAVE_RECEIVED);
			rebateLogModel.setTotalRebateCoin(getAllRebateDatas.weeklyDailyAward.getRebateCoins());
			rebateLogModel.setPlayerName(playerName);
			rebateLogModel.setPlayerId(playerID.toString());
			rebateLogModel.setType(RebateType.WEEKLY_FEE_DAILY_PAY.getId());
			rebateLogModel.setTypeDesc(RebateType.WEEKLY_FEE_DAILY_PAY.getDesc());

			//加到log list
			rebateLogModels.add(rebateLogModel);
			
			//更新包月每日獎勵 stage回db
			BankDAO.UpdatePlayerWeeklyFee(playerID, getAllRebateDatas.weeklyDailyAward.getBelongsDate(), getAllRebateDatas.weeklyDailyAward.getWeeklyFeePayStage(), RebateType.WEEKLY_FEE_DAILY_PAY);
		
			//新增到傳給統計的資訊中
			addCoinExpenditure(CoinExpenditureWay.WEEK_DAILY_REWARD, getAllRebateDatas.weeklyDailyAward.getRebateCoins());
			
		}
		
		
		if (getAllRebateDatas.rebateModels != null && getAllRebateDatas.rebateModels.size() > 0) {
			//&邀請獎勵
			for (RebateModel model : getAllRebateDatas.rebateModels) {
				// 錢加總
				getAllRebateDatas.totalGold = Helper.add(getAllRebateDatas.totalGold, model.getTotalRebateCoin());
				afterBankGold = Helper.add(afterBankGold, model.getTotalRebateCoin());
				
				//bank log
				BankLogModel bankLogModel = new BankLogModel();
				bankLogModel.setOrderId(orderId);
				bankLogModel.setAccountId(accountID.toString());
				bankLogModel.setPlayerId(playerID.toString());
				bankLogModel.setPlayerName(playerName);
				
				//提供給C幣統計使用的方式
				CoinExpenditureWay expenditureWay = null;
				
				if (model.getType() == RebateType.COMMISSION.getId()) {
					// 抽傭
					bankMoneychangeWay = BankMoneyChangeWay.ADD_INVITE_FRIEND_COMMISSION;
					bankLogModel.setRebateDate(model.getBelongsDate());
					expenditureWay = CoinExpenditureWay.INVITE_CODE_COMMISSION;
				} else if (model.getType() == RebateType.UPLINE_INVITE_AWARD.getId()) {
					// 邀請人獎勵
					bankMoneychangeWay = BankMoneyChangeWay.ADD_UPLINE_INVITE_REWARD;
					bankLogModel.setDownlineName(model.getDownlineName());
					expenditureWay = CoinExpenditureWay.INVITE_CODE_UPLINE_REWARD;
				} else if(model.getType() == RebateType.UPLINE_INVITE_AWARD_DISTRIBUTOR.getId()){
					// 邀請人獎勵
					bankMoneychangeWay = BankMoneyChangeWay.ADD_UPLINE_INVITE_REWARD;
					bankLogModel.setDownlineName(model.getDownlineName());
					expenditureWay = CoinExpenditureWay.INVITE_CODE_UPLINE_REWARD_DISTRIBUTOR;
				}
				
				bankLogModel.setBankGoldChangeValue(model.getTotalRebateCoin());
				bankLogModel.setBankGoldBeforeChange(Helper.sub(afterBankGold, model.getTotalRebateCoin()));
				bankLogModel.setBankGoldAfterChange(afterBankGold);
				bankLogModel.setChangeWay(bankMoneychangeWay.getId());
				bankLogModel.setChangeWayDesc(bankMoneychangeWay.getDesc());
				
				//加到log list 之後再一次寫到db
				bankLogModels.add(bankLogModel);

				// 寫抽佣部分 要重新new不然eventId會重複
				RebateLogModel rebateLogModel = new RebateLogModel();
				rebateLogModel.setOrderId(orderId);
				rebateLogModel.setType(model.getType());
				rebateLogModel.setTypeDesc(RebateType.values()[model.getType()-1].getDesc());
				rebateLogModel.setBelongsDate(model.getBelongsDate());
				rebateLogModel.setStatus(RebateModifyStatus.HAVE_RECEIVED);
				rebateLogModel.setTotalRebateCoin(model.getTotalRebateCoin());
				if (model.getType() == RebateType.UPLINE_INVITE_AWARD.getId() || model.getType() == RebateType.UPLINE_INVITE_AWARD_DISTRIBUTOR.getId()) {
					rebateLogModel.setDownlineId(model.getDownlineId());
					rebateLogModel.setDownlineName(model.getDownlineName());
				}
				rebateLogModel.setPlayerName(playerName);
				rebateLogModel.setPlayerId(model.getUplineId());
				rebateLogModels.add(rebateLogModel);
				
				//新增到傳給統計的資訊中
				addCoinExpenditure(expenditureWay, model.getTotalRebateCoin());
			} 
			
			//把改變的狀態寫回去 rebate model
			boolean updateSuccess = RebateDAO.updateRebateModelStatus(getAllRebateDatas.rebateModels,RebateModifyStatus.HAVE_RECEIVED);
			System.err.println(updateSuccess);
		}
		

		if(getAllRebateDatas.totalGold.signum() == 1)
			afterBankGold = BankDAO.UpdateBankMoney(playerID, getAllRebateDatas.totalGold);
		//寫banklogs
		for (BankLogModel bankLogModel : bankLogModels) {
			getCurrentModuleServer().saveDbLog(bankLogModel);
		}

		//寫rebatelogs
		for (RebateLogModel rebateLogModel : rebateLogModels) {
			getCurrentModuleServer().saveDbLog(rebateLogModel);
		}
		
		//送給C幣統計
		sendCoinExpenditureToAnalysis();
	}

	@Override
	public void callBackExecute(Object... userData) throws Exception {
		GameLobbyModule module = (GameLobbyModule) userData[0];
		Player playerData = module.getZone().getPlayer(playerID);

		SGetRebateCoinResponse response = new SGetRebateCoinResponse();

		if (getAllRebateDatas.totalGold.signum() == 1) {
			if (getAllRebateDatas.monthlyDailyAward.isSuccess()) {
				// 把包月資料寫回zone
				playerData.setMonthlyAwardTime(getAllRebateDatas.monthlyDailyAward.getBelongsDate());
				playerData.setMonthlyFeePayStage(getAllRebateDatas.monthlyDailyAward.getMonthlyFeePayStage());
			}
			if (getAllRebateDatas.weeklyDailyAward.isSuccess()) {
				// 把包月資料寫回zone
				playerData.setWeeklyAwardTime(getAllRebateDatas.weeklyDailyAward.getBelongsDate());
				playerData.setWeeklyFeePayStage(getAllRebateDatas.weeklyDailyAward.getWeeklyFeePayStage());
			}
			// 成功把錢寫回zone
			playerData.setBankGoldCoin(afterBankGold);
			
			response.errorCode = ErrorCode.SUCCESS;
			// 存成功
			response.bankGold = afterBankGold.toString(); // 銀行金幣
		} else {
			response.errorCode = ErrorCode.REBATE_COIN_DATA_ERROR;
		}
		MessageAction.sendMessage(sessionID, MessageTypes.S_GET_ALL_REBATE_RESPONS, response);
	}
	
	private void addCoinExpenditure(CoinExpenditureWay coinExpenditureWay, BigDecimal addValue){
		if(coinExpenditureWay == null || addValue == null || Helper.isLessEqual(addValue, BigDecimal.ZERO)){
			return;
		}
		
		BigDecimal ordinaryValue = sendToAnalysisMap.get(coinExpenditureWay);
		if(ordinaryValue == null){
			sendToAnalysisMap.put(coinExpenditureWay, addValue);
		}
		else{
			sendToAnalysisMap.put(coinExpenditureWay, Helper.add(ordinaryValue, addValue));
		}
	}
	
	private void sendCoinExpenditureToAnalysis(){
		if(sendToAnalysisMap.size() > 0){
			for(Entry<CoinExpenditureWay, BigDecimal> entry : sendToAnalysisMap.entrySet()){
				AnalysisGroupProcessor.sendCoinExpenditureToAnalysis(entry.getKey(), entry.getValue());
			}
		}
	}
}
